package QianFeng10.EchoDemo;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 网络编程TCP协议
 *
 * TCP程序概述
 * TCP是一个可靠的协议，面向连接的协议。
 * 实现TCP程序，需要编写服务器端和客户端，Java API为我们提供了java.net包，为实现网络应用程序提供类。
 * ServerSocket :此类实现服务器套接字。
 * Socket:此类实现客户端套接字(也可以就叫“套接字”)。
 * Socket是网络驱动层提供给应用程序编程的接口和-一种机制。
 *
 * 实现服务器端客户端程序
 * 服务器端:
 * public class ServerSocket extends Object
 *      此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作，然后可能向请求者返回结果。
 * ServerSocket(int port)
 *      创建绑定到特定端口的服务器套接字。
 * void setSoTimeout(int timeout)
 *      通过指定超时值启用/禁用so_ _TIMEOUT,以毫秒为单位。
 * InertAddress getInertAddress()
 *      返回此服务器套接字的本地地址。
 * Socket accept()
 *      侦听并接受到此套接字的连接。
 * 客户端:
 * public class Socket extends Object
 *      此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
 * Socket(String host, int port)
 *      创建一一个流套接字并将其连接到指定主机上的指定端口号。
 * InputStream getInputStream()
 *      返回此套接字的输入流。
 * OutputStream getOutputStream()
 *      返回此套接字的输出流。
 * void setSoTimeout(int timeout)
 *      启用/禁用带有指定超时值的 so_ _TIMEOUT，以毫秒为单位。
 *
 * Echo,意为应答，程序的功能是客户端向服务器发送一个字符串，
 * 服务器不做任何处理，直接把字符串返回给客户端，
 * Echo程序是最为基本的客户/服务器程序。
 **/
public class EchoServerDemo {
    public static void main(String[] args) {
        try {
            //创建一个服务器端的Socket(1024-65535)
            ServerSocket serverSocket = new ServerSocket(6666);
            System.out.println("服务器已启动，正在等待客户端的连接...");
            //等待客户端的连接，造成阻塞，如果有客户端连接成功，立即返回一个Socket对象
            Socket socket = serverSocket.accept();
            System.out.println("客户端连接成功" + serverSocket.getInetAddress());
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //通过输入流读取网络数据，如果没有数据，那么会造成阻塞
            String info = br.readLine();
            System.out.println(info);
            //获取输出流，向客户端返回消息
            PrintStream printStream = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
            printStream.println("echo:" + info);
            printStream.flush();
            printStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
